using System;

namespace Commons.Utils
{
	public class AsyncResult<T>
	{
		public bool HasData
		{
			get
			{
				return !object.Equals(Data, default(T));
			}
		}

		protected bool pending = true;
		public virtual bool HasPendingResult 
		{
			get
			{
				return pending && (Expiration.HasValue ? DateTime.Now < Expiration.Value : true);
			}
		}

		public bool HasError
		{
			get
			{
				return !HasPendingResult && !HasData; 
			}
		}

		public virtual string Error { get; protected set; }

		public virtual T Data { get; protected set; }

		public DateTime? Expiration { get; protected set; }

		public AsyncResult(int timeout)
		{
			pending = true;
			Expiration = DateTime.Now.Add(TimeSpan.FromMilliseconds(timeout));
		}

		public AsyncResult()
		{
			pending = true;
		}

		public AsyncResult(T data)
		{
			FillData(data);
		}

		public void FillData(T data)
		{
			Data = data;
			pending = false;
		}

		public void SetError(string error, params object[] args)
		{
			Data = default(T);
			Error = args.Length == 0 ? error : string.Format(error, args);
			pending = false;
		}
	}
}

